#include"thttpd.h"
#include <sys/types.h>
#include <sys/wait.h>
#include "custom_handle.h"
#include <sys/stat.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// 声明全局共享内存地址变量
 DeviceData *shm_addr = NULL;

// 初始化消息队列所需的目录
int init_msg_queue_dir() {
    const char *msg_dir = "/tmp/ipc/msgqueue/peer/";
    struct stat st;
    
    // 检查目录是否存在
    if (stat(msg_dir, &st) == -1) {
        printf("消息队列目录不存在，正在创建: %s\n", msg_dir);
        
        // 创建多级目录（-p参数确保父目录不存在时也能创建）
        char cmd[256];
        snprintf(cmd, sizeof(cmd), "mkdir -p %s", msg_dir);
        if (system(cmd) != 0) {
            perror("创建消息队列目录失败");
            return -1;
        }
        printf("消息队列目录创建成功\n");
    }
    return 0;
}
// 打印共享内存数据的函数
void print_shared_memory_data() {
    if (shm_addr == NULL) {
        printf("共享内存未初始化\n");
        return;
    }

    printf("\n===== 共享内存数据开始 =====");
    
    // 打印STM32数据
    printf("\nSTM32 数据 (%d 条):", shm_addr->stm32_count);
    for (int i = 0; i < shm_addr->stm32_count && i < 8; i++) {
        printf("\n第 %d 条:", i + 1);
        printf("\n  key: %d", shm_addr->stm32_list[i].key);
        printf("\n  name: %s", shm_addr->stm32_list[i].name);
        printf("\n  type: %d", shm_addr->stm32_list[i].type);
        printf("\n  typeStata: %d", shm_addr->stm32_list[i].typeStata);
        printf("\n  value: %d", shm_addr->stm32_list[i].value);
        printf("\n  floatValue: %.2f", shm_addr->stm32_list[i].floatValue);
    }
	//暂时注释
 /*       
    // 打印Modbus数据
    printf("\n\nModbus 数据 (%d 条):", shm_addr->modbus_count);
    for (int i = 0; i < shm_addr->modbus_count && i < 6; i++) {
        printf("\n第 %d 条:", i + 1);
        printf("\n  key: %d", shm_addr->modbus_list[i].key);
        printf("\n  name: %s", shm_addr->modbus_list[i].name);
        printf("\n  addr: %d", shm_addr->modbus_list[i].addr);
        printf("\n  type: %d", shm_addr->modbus_list[i].type);
        printf("\n  typeStata: %d", shm_addr->modbus_list[i].typeStata);
        printf("\n  value: %d", shm_addr->modbus_list[i].value);
    }
    
    // 打印MetaServer数据
    printf("\n\nMetaServer 数据 (%d 条):", shm_addr->meta_count);
    for (int i = 0; i < shm_addr->meta_count && i < 7; i++) {
        printf("\n第 %d 条:", i + 1);
        printf("\n  key: %d", shm_addr->meta_list[i].key);
        printf("\n  name: %s", shm_addr->meta_list[i].name);
        printf("\n  type: %d", shm_addr->meta_list[i].type);
        printf("\n  typeStata: %d", shm_addr->meta_list[i].typeStata);
        printf("\n  addr: %d", shm_addr->meta_list[i].addr);
        printf("\n  value: %d", shm_addr->meta_list[i].value);
    }
    */
    printf("\n===== 共享内存数据结束 =====\n\n");
}
static void* msg_request(void *arg)
{
	//这里客户端描述符通过参数传进来了
	int sock=(int)arg;

	// 一般情况下，线程终止后，其终止状态一直保留到其它线程调用pthread_join获取它的状态为止。
	//但是线程也可以被置为detach状态，这样的线程一旦终止就立刻回收它占用的所有资源，而不保留终止状态。
	pthread_detach(pthread_self());	

	//handler_msg作为所有的请求处理入口
	return (void*)handler_msg(sock);
}

int main(int argc,char* argv[])
{
     // 首先初始化消息队列目录（必须在共享内存初始化之前）
    if (init_msg_queue_dir() != 0) {
        fprintf(stderr, "消息队列目录初始化失败，程序退出\n");
        return 1;
    }
	 // 初始化共享内存
    shm_addr = init_shared_memory();
    if (shm_addr == NULL) {
        fprintf(stderr, "共享内存初始化失败，程序退出\n");
        return 1;
    }
    
    // 打印一次共享内存数据
    print_shared_memory_data();

	//如果不传递端口，那么使用默认端口80
	int port = 80;

	if(argc > 1)
	{
		port = atoi(argv[1]);
	}

	//初始化服务器
	int lis_sock=init_server(port);
	if (lis_sock < 0) {
        fprintf(stderr, "服务器初始化失败，程序退出\n");
        return 1;
    }
    
    printf("服务器启动成功，监听端口: %d\n", port);
	while(1)
	{
		struct sockaddr_in peer;
		socklen_t len=sizeof(peer);
		
		int sock=accept(lis_sock,(struct sockaddr*)&peer,&len);
		
		if(sock<0)
		{
			perror("accept failed");
			continue;
		}
		
		//每次接收一个链接后，会自动创建一个线程，这实际上就是线程服务器模型的应用
		pthread_t tid;
		if(pthread_create(&tid,NULL,msg_request,(void*)sock)>0)
		{
			perror("pthread_create failed");
			close(sock);
		}
		
	}
	return 0;
}
